package com.gdust.lease.web.admin.custom.interceptor;

import com.gdust.lease.common.login.LoginUser;
import com.gdust.lease.common.login.LoginUserHolder;
import com.gdust.lease.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * ClassName: AuthenticationInterceptor
 * Package: com.gdust.lease.web.admin.custom.interceptor
 * Description:认证拦截器
 * 该拦截器用于在处理请求前进行 JWT 令牌验证，以确保用户的身份合法性。
 *
 * 前置处理（preHandle()方法）：该方法在执行控制器方法之前执行。返回值为Boolean类型，如
 * 果返回false，表示拦截请求，不再向下执行，如果返回true，表示放行，程序继续向下执行（如果
 * 后面没有其他Interceptor，就会执行controller方法）。
 * @Author syun
 * @Create 2025/2/7 20:33
 * @Version 1.0
 */
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {
//    @Override
//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        String token = request.getHeader("access-token");
//        JwtUtil.parseToken(token);
//        return true;
//    }


    /**
     * 处理请求前进行身份认证
     * //返回值true放行，false则拦截
     * @param request  当前的 HTTP 请求对象
     * @param response 当前的 HTTP 响应对象
     * @param handler  处理器（控制器方法）
     * @return 返回 `true` 表示请求通过拦截器校验并继续执行，返回 `false` 表示拦截请求
     * @throws Exception 如果令牌解析失败，则可能抛出异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //注1：一般情况下前端把token放在请求头
        //注2：我们约定，前端登录后，后续请求都将JWT，放置于HTTP请求的Header中，其Header的key为`access-token`。
        // 从 HTTP 请求头中获取 JWT 令牌
        String token = request.getHeader("access-token");

        // 解析令牌，获取 Claims（负载信息）
        Claims claims = JwtUtil.parseToken(token);
        // 从 Claims 中提取用户 ID 和用户名
        Long userId = claims.get("userId", Long.class);
        String username = claims.get("username", String.class);
        // 将用户信息存入 ThreadLocal 变量，供后续业务逻辑使用
        LoginUserHolder.setLoginUser(new LoginUser(userId,username));

        //token在parseToken解析中没有发生异常,token合法,则放行
        return true;
    }

    /**
     * @Description 清理用户信息
     * @param request 当前的HTTP请求
     * @param response 当前的HTTP响应
     * @param handler 启动异步执行的处理器，用于类型和/或实例检查
     * @param ex 在处理器执行期间抛出的任何异常（如果有）；这不包括已通过异常解析器处理的异常
     * @throws Exception
     */
//    @Override
//    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//        LoginUserHolder.clear();
//    }

}
